#include <cstdlib>
#include <func.h>
#include <sys/socket.h>
#include <unistd.h>


int main()
{
    //1. 创建监听的套接字
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if(listenfd < 0) {
        perror("socket");
        return EXIT_FAILURE;
    }

    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(8000);
    //serveraddr.sin_addr.s_addr = inet_addr("192.168.30.129");
    serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");//代表本机地址

    //2. 绑定网络地址
    int ret = bind(listenfd, (const struct sockaddr*)&serveraddr, sizeof(serveraddr));
    if(ret < 0) {
        perror("bind");
        close(listenfd);
        return EXIT_FAILURE;
    }

    //3. 监听新连接的到来
    ret = listen(listenfd, 1);
    if(ret < 0) {
        perror("listen");
        close(listenfd);
        return EXIT_FAILURE;
    }

    //服务器模型：循环迭代式服务器
    while(1) {
        struct sockaddr_in clientaddr;
        memset(&clientaddr, 0, sizeof(clientaddr));
        socklen_t len = sizeof(clientaddr);

        //4. 获取到与对端进行通信的套接字netfd,它是listenfd的分身
        int netfd = accept(listenfd, (struct sockaddr*)&clientaddr, &len);
        if(netfd < 0) {
            perror("accept");
            continue;
        }
        //与对端进行通信操作
        //msg代表的是用户态发送缓冲区
        const char msg[1024] = "welcome to server";
        //对于数组使用sizeof运算符,获取的是数组的长度
        //不是字符串的长度
        //ret = send(netfd, msg, sizeof(msg), 0);
        //注意：在发送数据时，建议使用strlen来获取字符串长度
        //而且要设计获取返回值
        ret = send(netfd, msg, strlen(msg), 0);
        printf("send %d bytes.\n", ret);

        //buff代表的是用户态接收缓冲区
        char buff[1024] = {0};
        ret = recv(netfd, buff, sizeof(buff), 0);
        printf("recv from client %d bytes, %s\n", ret, buff);
    }


    close(listenfd);
    return 0;
}

